package com.colorlight.cloud.gateway.api.message.interceptor.trans;

import com.colorlight.cloud.gateway.api.exception.ReflexException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.*;
import java.util.Objects;

/**
 * @author Demon
 * @date 25/12/2023  上午11:53
 * proto转java
 */

public interface TransFromProtoInterceptor {
	Logger log = LoggerFactory.getLogger(TransFromProtoInterceptor.class);
	/**
	 * 拦截器入口 判断条件
	 * @param aClass 参数类型，过滤器入口
	 * @author Demon
	 * @date 18/12/2023/下午5:36
	 * @return 是否拦截
	 */
	Boolean isInterceptor(Class<?> aClass);
	/**
	 *  添加属性
	 * @throws NullPointerException 存在异常，详情看代码
	 * @param transObject 需要赋值得Java对象
	 * @param value 参数属性 {@link TransFromProtoInterceptor#getValue(String methodName, Object protoObject) }的返回值，为原始的数值，根据不同实现需要对应的转化
	 * @param inputClass  反射调用方法入参类型
	 * @param methodName 方法名
	 * @author Demon
	 * @date 25/12/2023/下午2:39
	 * @date 18/12/2023/下午5:42
	 */
  void addAttribute(Object transObject, Object value, Class<?> inputClass, String methodName);

	/**
	 * 根据方法名，反射获取 属性
	 * @param methodName 方法名字
	 * @param protoObject 获取方法得对象
	 * @author Demon
	 * @date 25/12/2023/下午1:44
	 * @return 获取proto协议提供的属性
	 */
	default Object getValue(String methodName, Object protoObject){
		Method method = null;
		try {
			method = protoObject.getClass().getMethod(methodName);
		} catch (NoSuchMethodException e) {
			log.warn("Proto 对象 {}未找方法{},存在协议版本落后",protoObject.getClass(),methodName);
			return null;
		}
		try {
			return method.invoke(protoObject);
		} catch (IllegalAccessException | InvocationTargetException e) {
			throw new ReflexException("proto获取属性方法失败");
		}
	}
	
	/**
	 * 根据名字提供者的get方法
	 *
	 * @param name 属性名
	 * @author Demon
	 * @date 17/12/2023/下午3:48
	 * @return 方法名
	 */
	default String getProtoMethodName(String name){
		if (Objects.isNull(name) || name.length() == 0) {
			throw new ReflexException("sdk转化方法名异常");
		}
		return "get" + Character.toUpperCase(name.charAt(0)) + name.substring(1);
	}
	
	
	/**
	 * 根据名字获取当前方法的set方法名
	 *
	 * @param name 属性名
	 * @author Demon
	 * @date 17/12/2023/下午3:48
	 * @return 方法名
	 */
	default String getMethodName(String name){
		if (Objects.isNull(name) || name.length() == 0) {
			throw new ReflexException("sdk转化方法名异常");
		}
		return "set" + Character.toUpperCase(name.charAt(0)) + name.substring(1);
	}
	

  /**
   * 参数类型转化:反射调用方法入参类型
   *
   * @param field 原始参数对象
   * @author Demon
   * @date 25/12/2023/下午2:41
   * @return 反射调用方法入参类型
   */
  default Class<?> getInputClass(Field field){
	  return field.getType();
  }
}
